package com.jmyd.sharding.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
 * 时间工具类
 *
 * @author samphin
 * @date 2021-6-17 17:22:39
 */
public final class DateTool {

    private DateTool() {
    }

    /**
     * 年月日时分秒格式
     * yyyy-MM-dd HH:mm:ss
     */
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 年月日格式
     * yyyy-MM-dd
     */
    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    /**
     * (2位年)月日时分秒格式
     * yyMMddHHmmss
     */
    public final static String YYMMDDHHMMSS = "yyMMddHHmmss";

    /**
     * 时间戳格式
     * yyyyMMddHHmmssSSS
     */
    public final static String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";

    /**
     * 时分格式
     * HH:mm
     */
    public static final String HH_MM = "HH:mm";

    /**
     * 年月格式
     * yyyy-MM
     */
    public static final String YYYY_MM = "yyyy-MM";

    /**
     * 年格式
     * yyyy
     */
    public static final String YYYY = "yyyy";

    /**
     * 年月日-时 格式
     * yyyy-MM-dd HH:mm
     */
    public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";

    /**
     * 年月日-时 格式
     * yyyy-MM-dd HH
     */
    public static final String YYYY_MM_DD_HH = "yyyy-MM-dd HH";

    //获取分钟前/后的时间
    public static String getTime(int num) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, num);
        return FastDateFormat.getInstance(YYYY_MM_DD_HH_MM_SS).format(cal.getTimeInMillis());
    }

    /**
     * 获取现在时间
     * yyyyMMddHHmmss
     */
    public static String getStringAllDate(Date date) {
        if (null == date) {
            date = new Date();
        }
        return FastDateFormat.getInstance(YYYYMMDDHHMMSSSSS).format(date);
    }

    /**
     * 时间格式化成字符串
     *
     * @param date    Date
     * @param pattern
     */
    public static String convertDateToStr(Date date, String pattern) {
        if (null == date) {
            return "";
        }
        return FastDateFormat.getInstance(pattern).format(date);
    }

    /**
     * 时间格式化成字符串 默认格式 yyyy-MM-dd HH:mm:ss
     *
     * @param date Date
     */
    public static String convertDateToStr(Date date) {
        return FastDateFormat.getInstance(YYYY_MM_DD_HH_MM_SS).format(date);
    }

    /**
     * 字符串转日期（yyyy-MM-dd HH:mm:ss）
     *
     * @param param
     */
    public static Date getDateFromStr(String param) {
        try {
            return FastDateFormat.getInstance(YYYY_MM_DD_HH_MM_SS).parse(param);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 字符串转日期（yyyy-MM-dd HH:mm:ss）
     *
     * @param dateString
     * @param pattern
     */
    public static Date getDateFormat(String dateString, String pattern) throws Exception {
        return FastDateFormat.getInstance(pattern).parse(dateString);
    }

    /**
     * 计算两个时间差
     *
     * @param date1
     * @param date2
     * @param timeUnit SECONDS、MINUTES、HOURS
     */
    public static Long timeDifference(Date date1, Date date2, TimeUnit timeUnit) {
        long c = Math.abs(date1.getTime() - date2.getTime()) / 1000;
        if (timeUnit == TimeUnit.SECONDS) {
            return c;
        }
        if (timeUnit == TimeUnit.MINUTES) {
            c = c / 60;
        } else if (timeUnit == TimeUnit.HOURS) {
            c = c / (60 * 60);
        }
        return c;
    }


    /**
     * 计算两个时间相差的天数
     *
     * @param early
     * @param late
     */
    public static int daysBetween(Date early, Date late) {
        long from = early.getTime();
        long to = late.getTime();
        return (int) ((to - from) / (1000 * 60 * 60 * 24));
    }

    /**
     * 获取当前时间
     */
    public static Date getTodayDate() {
        Calendar calendar = Calendar.getInstance();
        return calendar.getTime();
    }

    /**
     * 获取N天前的日期
     *
     * @param past
     */
    public static Date getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        return calendar.getTime();
    }

    /**
     * 获取N天后的日期
     *
     * @param past
     */
    public static Date getFetureDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        return calendar.getTime();
    }

    /**
     * 获取N天后的日期
     *
     * @param past
     */
    public static Date getFetureDate(Date date, int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
        return calendar.getTime();
    }

    public static Date getFetureMonth(Date date, int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, past);
        return calendar.getTime();
    }

    public static Date getFetureYear(Date date, int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, past);
        return calendar.getTime();
    }

    /**
     * 获取本周的第一天
     *
     * @return String
     **/
    public static Date getWeekStart() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.WEEK_OF_MONTH, 0);
        cal.set(Calendar.DAY_OF_WEEK, 2);
        return cal.getTime();
    }

    /**
     * 获取本周的最后一天
     *
     * @return String
     **/
    public static Date getWeekEnd() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.add(Calendar.DAY_OF_WEEK, 1);
        return cal.getTime();
    }

    /**
     * 获取年
     */
    public static int getYear() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.YEAR);
    }

    /**
     * 获取年
     */
    public static int getYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    /**
     * 获取月
     */
    public static int getMon() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取月
     */
    public static int getMon(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前季度
     */
    public static int getSeason(Date date) {
        int mon = getMon(date);
        BigDecimal bigDecimal = new BigDecimal(mon);
        BigDecimal bigDecimal1 = bigDecimal.divide(new BigDecimal(3), BigDecimal.ROUND_UP);
        return bigDecimal1.intValue();
    }

    /**
     * 获取天
     */
    public static int getDay() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.DATE);
    }

    /**
     * 获取天
     */
    public static int getDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DATE);
    }

    /**
     * 获取当前小时
     */
    public static int getHour() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.HOUR_OF_DAY);
    }

    public static int getHour(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取当前分钟
     */
    public static int getMinute() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.MINUTE);
    }

    /**
     * 获取当前分钟
     */
    public static int getMinute(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * 获取当前秒
     */
    public static int getSecond() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.SECOND);
    }

    /**
     * 获取当前秒
     */
    public static int getSecond(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.SECOND);
    }

    /**
     * 判断是否是同一天
     *
     * @param date1 时间1
     * @param date2 时间2
     */
    public static boolean isSameDate(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
        return isSameMonth && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定时间延后两天
     *
     * @param date
     */
    public static Long getDayLate2(Long date) throws Exception {
        Date d = timeStamp2Date(String.valueOf(date), YYYY_MM_DD_HH_MM_SS);
        d = getFetureDate(d, 2);
        return d.getTime() / 1000;
    }


    /**
     * Java将时间戳转换成指定格式日期字符串
     *
     * @param timestampString 时间戳 如："1473048265";
     * @param formats         要格式化的格式 默认："yyyy-MM-dd HH:mm:ss";
     * @return 返回结果 如："2016-09-05 16:06:42";
     */
    public static Date timeStamp2Date(String timestampString, String formats) throws Exception {
        if (StringUtils.isEmpty(formats)) {
            formats = YYYY_MM_DD_HH_MM_SS;
        }
        Long timestamp = Long.parseLong(timestampString) * 1000;
        String date = new SimpleDateFormat(formats, Locale.CHINA).format(new Date(timestamp));
        return getDateFormat(date, formats);
    }

    /**
     * 格式化日期 为 xxx 秒/分钟/小时前
     *
     * @param day1 结束时间
     * @param day2 开始时间
     * @return xxx 秒/分钟/小时前
     */
    public static String timeDiffFormmat(Date day1, Date day2) {
        Long seconds = DateTool.timeDifference(day1, day2, TimeUnit.SECONDS);
        if (seconds < 60) {
            return "刚刚";
        }
        Long minutes = DateTool.timeDifference(day1, day2, TimeUnit.MINUTES);
        if (minutes < 60) {
            return minutes + " 分钟前";
        }
        Long hours = DateTool.timeDifference(day1, day2, TimeUnit.HOURS);
        if (hours < 24) {
            return "今天 " + DateTool.convertDateToStr(day2, HH_MM);
        }
        int day = DateTool.daysBetween(day2, day1);
        if (day < 2) {
            return "昨天";
        }
        return day + " 天前";
    }
}
